package cn.net.xinyi.xs.service.hr.impl;

import java.util.List;

import javax.persistence.EntityExistsException;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.dao.DataIntegrityViolationException;

import cn.net.xinyi.xs.dao.hr.UserDao;
import cn.net.xinyi.xs.model.hr.User;
import cn.net.xinyi.xs.service.UserExistsException;
import cn.net.xinyi.xs.service.XinYiException;
import cn.net.xinyi.xs.service.hr.UserManager;
import cn.net.xinyi.xs.service.impl.BaseManager;
import cn.net.xinyi.xs.util.EncryptionUtil;

/**
 * Implementation of UserManager interface.
 * 
 * @author <a href="mailto:caihualin2009@gmail.com">Cai Hua</a>
 */
public class UserManagerImpl extends BaseManager implements UserManager {
	private UserDao dao;

	/**
	 * Set the Dao for communication with the data layer.
	 * 
	 * @param dao
	 *            the UserDao that communicates with the database
	 */
	@Required
	public void setUserDao(UserDao dao) {
		this.dao = dao;
	}

	/**
	 * {@inheritDoc}
	 */
	public User getUser(String userId) {
		return (User) dao.get(new Long(userId));
	}

	/**
	 * {@inheritDoc}
	 */
	public List<User> getUsers(User user) {
		return dao.getUsers();
	}

	/**
	 * {@inheritDoc}
	 */
	public User saveUser(User user) throws UserExistsException {

		if (user.getId() == null) {
			// if new user, lowercase userId
			user.setUserName(user.getUserName().toLowerCase());
		}

		try {
			return dao.saveUser(user);
		} catch (DataIntegrityViolationException e) {
			e.printStackTrace();
			log.warn(e.getMessage());
			throw new UserExistsException("User '" + user.getUserName()
					+ "' already exists!");
		} catch (EntityExistsException e) { // needed for JPA
			e.printStackTrace();
			log.warn(e.getMessage());
			throw new UserExistsException("User '" + user.getUserName()
					+ "' already exists!");
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public void removeUser(String userId) {
		log.debug("removing user: " + userId);
		dao.remove(User.class, new Long(userId));
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @param username
	 *            the login name of the human
	 * @return User the populated user object
	 */
	public User getUserByUserName(String userName) {
		return (User) dao.getUserByUserName(userName);
	}

	public User login(String userName, String password) throws XinYiException {
		User user = getUserByUserName(userName);
		if (user == null) {
			throw new XinYiException("errors.user.not.exist");
		} else if (!user.getPassword().equals(EncryptionUtil.encrypt(password))) {
			throw new XinYiException("errors.login.failed");
		}
		if (!user.isValid())
			throw new XinYiException("errors.user.forbided");
		return user;
	}
}
